<?php

declare(strict_types=1);

namespace sheep\library\install;

use sheep\library\install\traits\Env;
use sheep\library\console\Composer as ComposerProcess;
use sheep\exception\SheepException;
use sheep\facade\Redis;
use think\facade\Config;
use PDOException;
use PDO;
use app\admin\model\auth\Admin;
use yunwuxin\facade\Notification;
use think\facade\Log;

class InstallManager
{

    use Env;

    protected $isCli = false;

    protected $output = null;

    protected $provider = null;

    protected $runtimePath = null;

    public function __construct($output = null)
    {
        $this->output = $output;
        $this->isCli = request()->isCli();
        $this->provider();
        $this->setEnvFilePath();
        $this->runtimePath = root_path('runtime');
    }



    /**
     * 更新扩展包
     */
    public function updatePackages()
    {
        $composer = new ComposerProcess;
        if ($this->isCli) {
            $composer->setCallback(function ($message) {
                echo $message;
            });
        }
        $result = $composer->update();
        return $result;
    }



    /**
     * 执行数据迁移
     */
    public function databaseMigrate()
    {
        // 执行数据迁移，并将所有输出导入到 output 中
        exec(get_php() . ' ' . root_path() . 'think migrate:run 2>&1', $output);

        // 过滤空值，并输出结果
        $output = array_values(array_filter($output));

        if ($this->isCli) {
            foreach ($output as $o) {
                $this->output->writeln($o);
            }
        }

        $result = [
            'error' => strpos(end($output), 'All Done') !== false ? 0 : 1,
            'output' => $output
        ];

        return $result;
    }


    /**
     * 修改项目目录权限
     *
     * @param $username 用户名
     * @param $group 用户组
     * @return void
     */
    public function permission($username = 'www', $group = 'www')
    {
        // 修改项目目录权限
        exec('chown -R ' . $username . ':' . $group . ' ' . root_path() . ' 2>&1', $output);

        $output = array_values(array_filter($output));
        foreach ($output as $o) {
            $this->output->warning($o);
        }
    }


    /**
     * 检测 env 文件是否可写
     */
    public function checkEnvWritable()
    {
        // 复制 env 文件，并加载配置
        if (!file_exists($this->envFilePath)) {
            copy(root_path() . '.env.example', $this->envFilePath);
            $this->refreshEnvVars();
        }

        return is_writable($this->envFilePath);
    }



    /**
     * 将版本号写入程序中
     *
     * @param string $version
     * @return void
     */
    public function writeVersion($version)
    {
        $sheep_file = root_path('sheep' . DIRECTORY_SEPARATOR . 'service') . 'SheepService.php';
        $content = file_get_contents($sheep_file);

        $current_version = str_before(str_after($content, 'const VERSION = '), ';');
        file_put_contents($sheep_file, str_replace($current_version, "'" . $version . "'", $content));
    }



    /**
     * 检测 runtime 是否可写
     */
    protected function checkRuntimeWritable()
    {
        return is_writable($this->runtimePath);
    }


    protected function provider()
    {
        $provider = $this->isCli ? 'console' : 'view';

        $class = "\\sheep\\library\\install\\provider\\" . ucfirst($provider);

        $this->provider = new $class($this, $this->output);

        return $this->provider;
    }



    public function __call($function, $arguments)
    {
        return $this->provider->{$function}(...$arguments);
    }
}
